const express = require('express')
const apiKeyService = require('../../services/apiKeyService')
const ccrAccountService = require('../../services/ccrAccountService')
const claudeAccountService = require('../../services/claudeAccountService')
const claudeConsoleAccountService = require('../../services/claudeConsoleAccountService')
const geminiAccountService = require('../../services/geminiAccountService')
const geminiApiAccountService = require('../../services/geminiApiAccountService')
const openaiAccountService = require('../../services/openaiAccountService')
const openaiResponsesAccountService = require('../../services/openaiResponsesAccountService')
const droidAccountService = require('../../services/droidAccountService')
const redis = require('../../models/redis')
const { authenticateAdmin } = require('../../middleware/auth')
const logger = require('../../utils/logger')
const CostCalculator = require('../../utils/costCalculator')
const pricingService = require('../../services/pricingService')

const router = express.Router()

const accountTypeNames = {
  claude: 'Claude官方',
  'claude-console': 'Claude Console',
  ccr: 'Claude Console Relay',
  openai: 'OpenAI',
  'openai-responses': 'OpenAI Responses',
  gemini: 'Gemini',
  'gemini-api': 'Gemini API',
  droid: 'Droid',
  unknown: '未知渠道'
}

const resolveAccountByPlatform = async (accountId, platform) => {
  const serviceMap = {
    claude: claudeAccountService,
    'claude-console': claudeConsoleAccountService,
    gemini: geminiAccountService,
    'gemini-api': geminiApiAccountService,
    openai: openaiAccountService,
    'openai-responses': openaiResponsesAccountService,
    droid: droidAccountService,
    ccr: ccrAccountService
  }

  if (platform && serviceMap[platform]) {
    try {
      const account = await serviceMap[platform].getAccount(accountId)
      if (account) {
        return { ...account, platform }
      }
    } catch (error) {
      logger.debug(`⚠️ Failed to get account ${accountId} from ${platform}: ${error.message}`)
    }
  }

  for (const [platformName, service] of Object.entries(serviceMap)) {
    try {
      const account = await service.getAccount(accountId)
      if (account) {
        return { ...account, platform: platformName }
      }
    } catch (error) {
      logger.debug(`⚠️ Failed to get account ${accountId} from ${platformName}: ${error.message}`)
    }
  }

  return null
}

const getApiKeyName = async (keyId) => {
  try {
    const keyData = await redis.getApiKey(keyId)
    return keyData?.name || keyData?.label || keyId
  } catch (error) {
    logger.debug(`⚠️ Failed to get API key name for ${keyId}: ${error.message}`)
    return keyId
  }
}

// 📊 账户使用统计

// 获取所有账户的使用统计
router.get('/accounts/usage-stats', authenticateAdmin, async (req, res) => {
  try {
    const accountsStats = await redis.getAllAccountsUsageStats()

    return res.json({
      success: true,
      data: accountsStats,
      summary: {
        totalAccounts: accountsStats.length,
        activeToday: accountsStats.filter((account) => account.daily.requests > 0).length,
        totalDailyTokens: accountsStats.reduce(
          (sum, account) => sum + (account.daily.allTokens || 0),
          0
        ),
        totalDailyRequests: accountsStats.reduce(
          (sum, account) => sum + (account.daily.requests || 0),
          0
        )
      },
      timestamp: new Date().toISOString()
    })
  } catch (error) {
    logger.error('❌ Failed to get accounts usage stats:', error)
    return res.status(500).json({
      success: false,
      error: 'Failed to get accounts usage stats',
      message: error.message
    })
  }
})

// 获取单个账户的使用统计
router.get('/accounts/:accountId/usage-stats', authenticateAdmin, async (req, res) => {
  try {
    const { accountId } = req.params
    const accountStats = await redis.getAccountUsageStats(accountId)

    // 获取账户基本信息
    const accountData = await claudeAccountService.getAccount(accountId)
    if (!accountData) {
      return res.status(404).json({
        success: false,
        error: 'Account not found'
      })
    }

    return res.json({
      success: true,
      data: {
        ...accountStats,
        accountInfo: {
          name: accountData.name,
          email: accountData.email,
          status: accountData.status,
          isActive: accountData.isActive,
          createdAt: accountData.createdAt
        }
      },
      timestamp: new Date().toISOString()
    })
  } catch (error) {
    logger.error('❌ Failed to get account usage stats:', error)
    return res.status(500).json({
      success: false,
      error: 'Failed to get account usage stats',
      message: error.message
    })
  }
})

// 获取账号近30天使用历史
router.get('/accounts/:accountId/usage-history', authenticateAdmin, async (req, res) => {
  try {
    const { accountId } = req.params
    const { platform = 'claude', days = 30 } = req.query

    const allowedPlatforms = [
      'claude',
      'claude-console',
      'openai',
      'openai-responses',
      'gemini',
      'gemini-api',
      'droid'
    ]
    if (!allowedPlatforms.includes(platform)) {
      return res.status(400).json({
        success: false,
        error: 'Unsupported account platform'
      })
    }

    const accountTypeMap = {
      openai: 'openai',
      'openai-responses': 'openai-responses',
      'gemini-api': 'gemini-api',
      droid: 'droid'
    }

    const fallbackModelMap = {
      claude: 'claude-3-5-sonnet-20241022',
      'claude-console': 'claude-3-5-sonnet-20241022',
      openai: 'gpt-4o-mini-2024-07-18',
      'openai-responses': 'gpt-4o-mini-2024-07-18',
      gemini: 'gemini-1.5-flash',
      'gemini-api': 'gemini-2.0-flash',
      droid: 'unknown'
    }

    // 获取账户信息以获取创建时间
    let accountData = null
    let accountCreatedAt = null

    try {
      switch (platform) {
        case 'claude':
          accountData = await claudeAccountService.getAccount(accountId)
          break
        case 'claude-console':
          accountData = await claudeConsoleAccountService.getAccount(accountId)
          break
        case 'openai':
          accountData = await openaiAccountService.getAccount(accountId)
          break
        case 'openai-responses':
          accountData = await openaiResponsesAccountService.getAccount(accountId)
          break
        case 'gemini':
          accountData = await geminiAccountService.getAccount(accountId)
          break
        case 'gemini-api': {
          accountData = await geminiApiAccountService.getAccount(accountId)
          break
        }
        case 'droid':
          accountData = await droidAccountService.getAccount(accountId)
          break
      }

      if (accountData && accountData.createdAt) {
        accountCreatedAt = new Date(accountData.createdAt)
      }
    } catch (error) {
      logger.warn(`Failed to get account data for avgDailyCost calculation: ${error.message}`)
    }

    const client = redis.getClientSafe()
    const fallbackModel = fallbackModelMap[platform] || 'unknown'
    const daysCount = Math.min(Math.max(parseInt(days, 10) || 30, 1), 60)

    // 获取概览统计数据
    const accountUsageStats = await redis.getAccountUsageStats(
      accountId,
      accountTypeMap[platform] || null
    )

    const history = []
    let totalCost = 0
    let totalRequests = 0
    let totalTokens = 0

    let highestCostDay = null
    let highestRequestDay = null

    const sumModelCostsForDay = async (dateKey) => {
      const modelPattern = `account_usage:model:daily:${accountId}:*:${dateKey}`
      const modelKeys = await client.keys(modelPattern)
      let summedCost = 0

      if (modelKeys.length === 0) {
        return summedCost
      }

      for (const modelKey of modelKeys) {
        const modelParts = modelKey.split(':')
        const modelName = modelParts[4] || 'unknown'
        const modelData = await client.hgetall(modelKey)
        if (!modelData || Object.keys(modelData).length === 0) {
          continue
        }

        const usage = {
          input_tokens: parseInt(modelData.inputTokens) || 0,
          output_tokens: parseInt(modelData.outputTokens) || 0,
          cache_creation_input_tokens: parseInt(modelData.cacheCreateTokens) || 0,
          cache_read_input_tokens: parseInt(modelData.cacheReadTokens) || 0
        }

        const costResult = CostCalculator.calculateCost(usage, modelName)
        summedCost += costResult.costs.total
      }

      return summedCost
    }

    const today = new Date()

    for (let offset = daysCount - 1; offset >= 0; offset--) {
      const date = new Date(today)
      date.setDate(date.getDate() - offset)

      const tzDate = redis.getDateInTimezone(date)
      const dateKey = redis.getDateStringInTimezone(date)
      const monthLabel = String(tzDate.getUTCMonth() + 1).padStart(2, '0')
      const dayLabel = String(tzDate.getUTCDate()).padStart(2, '0')
      const label = `${monthLabel}/${dayLabel}`

      const dailyKey = `account_usage:daily:${accountId}:${dateKey}`
      const dailyData = await client.hgetall(dailyKey)

      const inputTokens = parseInt(dailyData?.inputTokens) || 0
      const outputTokens = parseInt(dailyData?.outputTokens) || 0
      const cacheCreateTokens = parseInt(dailyData?.cacheCreateTokens) || 0
      const cacheReadTokens = parseInt(dailyData?.cacheReadTokens) || 0
      const allTokens =
        parseInt(dailyData?.allTokens) ||
        inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens
      const requests = parseInt(dailyData?.requests) || 0

      let cost = await sumModelCostsForDay(dateKey)

      if (cost === 0 && allTokens > 0) {
        const fallbackUsage = {
          input_tokens: inputTokens,
          output_tokens: outputTokens,
          cache_creation_input_tokens: cacheCreateTokens,
          cache_read_input_tokens: cacheReadTokens
        }
        const fallbackResult = CostCalculator.calculateCost(fallbackUsage, fallbackModel)
        cost = fallbackResult.costs.total
      }

      const normalizedCost = Math.round(cost * 1_000_000) / 1_000_000

      totalCost += normalizedCost
      totalRequests += requests
      totalTokens += allTokens

      if (!highestCostDay || normalizedCost > highestCostDay.cost) {
        highestCostDay = {
          date: dateKey,
          label,
          cost: normalizedCost,
          formattedCost: CostCalculator.formatCost(normalizedCost)
        }
      }

      if (!highestRequestDay || requests > highestRequestDay.requests) {
        highestRequestDay = {
          date: dateKey,
          label,
          requests
        }
      }

      history.push({
        date: dateKey,
        label,
        cost: normalizedCost,
        formattedCost: CostCalculator.formatCost(normalizedCost),
        requests,
        tokens: allTokens
      })
    }

    // 计算实际使用天数（从账户创建到现在）
    let actualDaysForAvg = daysCount
    if (accountCreatedAt) {
      const now = new Date()
      const diffTime = Math.abs(now - accountCreatedAt)
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
      // 使用实际使用天数，但不超过请求的天数范围
      actualDaysForAvg = Math.min(diffDays, daysCount)
      // 至少为1天，避免除零
      actualDaysForAvg = Math.max(actualDaysForAvg, 1)
    }

    // 使用实际天数计算日均值
    const avgDailyCost = actualDaysForAvg > 0 ? totalCost / actualDaysForAvg : 0
    const avgDailyRequests = actualDaysForAvg > 0 ? totalRequests / actualDaysForAvg : 0
    const avgDailyTokens = actualDaysForAvg > 0 ? totalTokens / actualDaysForAvg : 0

    const todayData = history.length > 0 ? history[history.length - 1] : null

    return res.json({
      success: true,
      data: {
        history,
        summary: {
          days: daysCount,
          actualDaysUsed: actualDaysForAvg, // 实际使用的天数（用于计算日均值）
          accountCreatedAt: accountCreatedAt ? accountCreatedAt.toISOString() : null,
          totalCost,
          totalCostFormatted: CostCalculator.formatCost(totalCost),
          totalRequests,
          totalTokens,
          avgDailyCost,
          avgDailyCostFormatted: CostCalculator.formatCost(avgDailyCost),
          avgDailyRequests,
          avgDailyTokens,
          today: todayData
            ? {
                date: todayData.date,
                cost: todayData.cost,
                costFormatted: todayData.formattedCost,
                requests: todayData.requests,
                tokens: todayData.tokens
              }
            : null,
          highestCostDay,
          highestRequestDay
        },
        overview: accountUsageStats,
        generatedAt: new Date().toISOString()
      }
    })
  } catch (error) {
    logger.error('❌ Failed to get account usage history:', error)
    return res.status(500).json({
      success: false,
      error: 'Failed to get account usage history',
      message: error.message
    })
  }
})

// 📊 使用趋势和成本分析

// 获取使用趋势数据
router.get('/usage-trend', authenticateAdmin, async (req, res) => {
  try {
    const { days = 7, granularity = 'day', startDate, endDate } = req.query
    const client = redis.getClientSafe()

    const trendData = []

    if (granularity === 'hour') {
      // 小时粒度统计
      let startTime, endTime

      if (startDate && endDate) {
        // 使用自定义时间范围
        startTime = new Date(startDate)
        endTime = new Date(endDate)

        // 调试日志
        logger.info('📊 Usage trend hour granularity - received times:')
        logger.info(`  startDate (raw): ${startDate}`)
        logger.info(`  endDate (raw): ${endDate}`)
        logger.info(`  startTime (parsed): ${startTime.toISOString()}`)
        logger.info(`  endTime (parsed): ${endTime.toISOString()}`)
        logger.info(
          `  System timezone offset: ${require('../../../config/config').system.timezoneOffset || 8}`
        )
      } else {
        // 默认最近24小时
        endTime = new Date()
        startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000)
      }

      // 确保时间范围不超过24小时
      const timeDiff = endTime - startTime
      if (timeDiff > 24 * 60 * 60 * 1000) {
        return res.status(400).json({
          error: '小时粒度查询时间范围不能超过24小时'
        })
      }

      // 按小时遍历
      const currentHour = new Date(startTime)
      currentHour.setMinutes(0, 0, 0)

      while (currentHour <= endTime) {
        // 注意：前端发送的时间已经是UTC时间，不需要再次转换
        // 直接从currentHour生成对应系统时区的日期和小时
        const tzCurrentHour = redis.getDateInTimezone(currentHour)
        const dateStr = redis.getDateStringInTimezone(currentHour)
        const hour = String(tzCurrentHour.getUTCHours()).padStart(2, '0')
        const hourKey = `${dateStr}:${hour}`

        // 获取当前小时的模型统计数据
        const modelPattern = `usage:model:hourly:*:${hourKey}`
        const modelKeys = await client.keys(modelPattern)

        let hourInputTokens = 0
        let hourOutputTokens = 0
        let hourRequests = 0
        let hourCacheCreateTokens = 0
        let hourCacheReadTokens = 0
        let hourCost = 0

        for (const modelKey of modelKeys) {
          const modelMatch = modelKey.match(/usage:model:hourly:(.+):\d{4}-\d{2}-\d{2}:\d{2}$/)
          if (!modelMatch) {
            continue
          }

          const model = modelMatch[1]
          const data = await client.hgetall(modelKey)

          if (data && Object.keys(data).length > 0) {
            const modelInputTokens = parseInt(data.inputTokens) || 0
            const modelOutputTokens = parseInt(data.outputTokens) || 0
            const modelCacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
            const modelCacheReadTokens = parseInt(data.cacheReadTokens) || 0
            const modelRequests = parseInt(data.requests) || 0

            hourInputTokens += modelInputTokens
            hourOutputTokens += modelOutputTokens
            hourCacheCreateTokens += modelCacheCreateTokens
            hourCacheReadTokens += modelCacheReadTokens
            hourRequests += modelRequests

            const modelUsage = {
              input_tokens: modelInputTokens,
              output_tokens: modelOutputTokens,
              cache_creation_input_tokens: modelCacheCreateTokens,
              cache_read_input_tokens: modelCacheReadTokens
            }
            const modelCostResult = CostCalculator.calculateCost(modelUsage, model)
            hourCost += modelCostResult.costs.total
          }
        }

        // 如果没有模型级别的数据，尝试API Key级别的数据
        if (modelKeys.length === 0) {
          const pattern = `usage:hourly:*:${hourKey}`
          const keys = await client.keys(pattern)

          for (const key of keys) {
            const data = await client.hgetall(key)
            if (data) {
              hourInputTokens += parseInt(data.inputTokens) || 0
              hourOutputTokens += parseInt(data.outputTokens) || 0
              hourRequests += parseInt(data.requests) || 0
              hourCacheCreateTokens += parseInt(data.cacheCreateTokens) || 0
              hourCacheReadTokens += parseInt(data.cacheReadTokens) || 0
            }
          }

          const usage = {
            input_tokens: hourInputTokens,
            output_tokens: hourOutputTokens,
            cache_creation_input_tokens: hourCacheCreateTokens,
            cache_read_input_tokens: hourCacheReadTokens
          }
          const costResult = CostCalculator.calculateCost(usage, 'unknown')
          hourCost = costResult.costs.total
        }

        // 格式化时间标签 - 使用系统时区的显示
        const tzDateForLabel = redis.getDateInTimezone(currentHour)
        const month = String(tzDateForLabel.getUTCMonth() + 1).padStart(2, '0')
        const day = String(tzDateForLabel.getUTCDate()).padStart(2, '0')
        const hourStr = String(tzDateForLabel.getUTCHours()).padStart(2, '0')

        trendData.push({
          // 对于小时粒度，只返回hour字段，不返回date字段
          hour: currentHour.toISOString(), // 保留原始ISO时间用于排序
          label: `${month}/${day} ${hourStr}:00`, // 添加格式化的标签
          inputTokens: hourInputTokens,
          outputTokens: hourOutputTokens,
          requests: hourRequests,
          cacheCreateTokens: hourCacheCreateTokens,
          cacheReadTokens: hourCacheReadTokens,
          totalTokens:
            hourInputTokens + hourOutputTokens + hourCacheCreateTokens + hourCacheReadTokens,
          cost: hourCost
        })

        // 移到下一个小时
        currentHour.setHours(currentHour.getHours() + 1)
      }
    } else {
      // 天粒度统计（保持原有逻辑）
      const daysCount = parseInt(days) || 7
      const today = new Date()

      // 获取过去N天的数据
      for (let i = 0; i < daysCount; i++) {
        const date = new Date(today)
        date.setDate(date.getDate() - i)
        const dateStr = redis.getDateStringInTimezone(date)

        // 汇总当天所有API Key的使用数据
        const pattern = `usage:daily:*:${dateStr}`
        const keys = await client.keys(pattern)

        let dayInputTokens = 0
        let dayOutputTokens = 0
        let dayRequests = 0
        let dayCacheCreateTokens = 0
        let dayCacheReadTokens = 0
        let dayCost = 0

        // 按模型统计使用量
        // const modelUsageMap = new Map();

        // 获取当天所有模型的使用数据
        const modelPattern = `usage:model:daily:*:${dateStr}`
        const modelKeys = await client.keys(modelPattern)

        for (const modelKey of modelKeys) {
          // 解析模型名称
          const modelMatch = modelKey.match(/usage:model:daily:(.+):\d{4}-\d{2}-\d{2}$/)
          if (!modelMatch) {
            continue
          }

          const model = modelMatch[1]
          const data = await client.hgetall(modelKey)

          if (data && Object.keys(data).length > 0) {
            const modelInputTokens = parseInt(data.inputTokens) || 0
            const modelOutputTokens = parseInt(data.outputTokens) || 0
            const modelCacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
            const modelCacheReadTokens = parseInt(data.cacheReadTokens) || 0
            const modelRequests = parseInt(data.requests) || 0

            // 累加总数
            dayInputTokens += modelInputTokens
            dayOutputTokens += modelOutputTokens
            dayCacheCreateTokens += modelCacheCreateTokens
            dayCacheReadTokens += modelCacheReadTokens
            dayRequests += modelRequests

            // 按模型计算费用
            const modelUsage = {
              input_tokens: modelInputTokens,
              output_tokens: modelOutputTokens,
              cache_creation_input_tokens: modelCacheCreateTokens,
              cache_read_input_tokens: modelCacheReadTokens
            }
            const modelCostResult = CostCalculator.calculateCost(modelUsage, model)
            dayCost += modelCostResult.costs.total
          }
        }

        // 如果没有模型级别的数据，回退到原始方法
        if (modelKeys.length === 0 && keys.length > 0) {
          for (const key of keys) {
            const data = await client.hgetall(key)
            if (data) {
              dayInputTokens += parseInt(data.inputTokens) || 0
              dayOutputTokens += parseInt(data.outputTokens) || 0
              dayRequests += parseInt(data.requests) || 0
              dayCacheCreateTokens += parseInt(data.cacheCreateTokens) || 0
              dayCacheReadTokens += parseInt(data.cacheReadTokens) || 0
            }
          }

          // 使用默认模型价格计算
          const usage = {
            input_tokens: dayInputTokens,
            output_tokens: dayOutputTokens,
            cache_creation_input_tokens: dayCacheCreateTokens,
            cache_read_input_tokens: dayCacheReadTokens
          }
          const costResult = CostCalculator.calculateCost(usage, 'unknown')
          dayCost = costResult.costs.total
        }

        trendData.push({
          date: dateStr,
          inputTokens: dayInputTokens,
          outputTokens: dayOutputTokens,
          requests: dayRequests,
          cacheCreateTokens: dayCacheCreateTokens,
          cacheReadTokens: dayCacheReadTokens,
          totalTokens: dayInputTokens + dayOutputTokens + dayCacheCreateTokens + dayCacheReadTokens,
          cost: dayCost,
          formattedCost: CostCalculator.formatCost(dayCost)
        })
      }
    }

    // 按日期正序排列
    if (granularity === 'hour') {
      trendData.sort((a, b) => new Date(a.hour) - new Date(b.hour))
    } else {
      trendData.sort((a, b) => new Date(a.date) - new Date(b.date))
    }

    return res.json({ success: true, data: trendData, granularity })
  } catch (error) {
    logger.error('❌ Failed to get usage trend:', error)
    return res.status(500).json({ error: 'Failed to get usage trend', message: error.message })
  }
})

// 获取单个API Key的模型统计
router.get('/api-keys/:keyId/model-stats', authenticateAdmin, async (req, res) => {
  try {
    const { keyId } = req.params
    const { period = 'monthly', startDate, endDate } = req.query

    logger.info(
      `📊 Getting model stats for API key: ${keyId}, period: ${period}, startDate: ${startDate}, endDate: ${endDate}`
    )

    const client = redis.getClientSafe()
    const today = redis.getDateStringInTimezone()
    const tzDate = redis.getDateInTimezone()
    const currentMonth = `${tzDate.getUTCFullYear()}-${String(tzDate.getUTCMonth() + 1).padStart(
      2,
      '0'
    )}`

    let searchPatterns = []

    if (period === 'custom' && startDate && endDate) {
      // 自定义日期范围，生成多个日期的搜索模式
      const start = new Date(startDate)
      const end = new Date(endDate)

      // 确保日期范围有效
      if (start > end) {
        return res.status(400).json({ error: 'Start date must be before or equal to end date' })
      }

      // 限制最大范围为365天
      const daysDiff = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1
      if (daysDiff > 365) {
        return res.status(400).json({ error: 'Date range cannot exceed 365 days' })
      }

      // 生成日期范围内所有日期的搜索模式
      for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
        const dateStr = redis.getDateStringInTimezone(d)
        searchPatterns.push(`usage:${keyId}:model:daily:*:${dateStr}`)
      }

      logger.info(
        `📊 Custom date range patterns: ${searchPatterns.length} days from ${startDate} to ${endDate}`
      )
    } else {
      // 原有的预设期间逻辑
      const pattern =
        period === 'daily'
          ? `usage:${keyId}:model:daily:*:${today}`
          : `usage:${keyId}:model:monthly:*:${currentMonth}`
      searchPatterns = [pattern]
      logger.info(`📊 Preset period pattern: ${pattern}`)
    }

    // 汇总所有匹配的数据
    const modelStatsMap = new Map()
    const modelStats = [] // 定义结果数组

    for (const pattern of searchPatterns) {
      const keys = await client.keys(pattern)
      logger.info(`📊 Pattern ${pattern} found ${keys.length} keys`)

      for (const key of keys) {
        const match =
          key.match(/usage:.+:model:daily:(.+):\d{4}-\d{2}-\d{2}$/) ||
          key.match(/usage:.+:model:monthly:(.+):\d{4}-\d{2}$/)

        if (!match) {
          logger.warn(`📊 Pattern mismatch for key: ${key}`)
          continue
        }

        const model = match[1]
        const data = await client.hgetall(key)

        if (data && Object.keys(data).length > 0) {
          // 累加同一模型的数据
          if (!modelStatsMap.has(model)) {
            modelStatsMap.set(model, {
              requests: 0,
              inputTokens: 0,
              outputTokens: 0,
              cacheCreateTokens: 0,
              cacheReadTokens: 0,
              allTokens: 0
            })
          }

          const stats = modelStatsMap.get(model)
          stats.requests += parseInt(data.requests) || 0
          stats.inputTokens += parseInt(data.inputTokens) || 0
          stats.outputTokens += parseInt(data.outputTokens) || 0
          stats.cacheCreateTokens += parseInt(data.cacheCreateTokens) || 0
          stats.cacheReadTokens += parseInt(data.cacheReadTokens) || 0
          stats.allTokens += parseInt(data.allTokens) || 0
        }
      }
    }

    // 将汇总的数据转换为最终结果
    for (const [model, stats] of modelStatsMap) {
      logger.info(`📊 Model ${model} aggregated data:`, stats)

      const usage = {
        input_tokens: stats.inputTokens,
        output_tokens: stats.outputTokens,
        cache_creation_input_tokens: stats.cacheCreateTokens,
        cache_read_input_tokens: stats.cacheReadTokens
      }

      // 使用CostCalculator计算费用
      const costData = CostCalculator.calculateCost(usage, model)

      modelStats.push({
        model,
        requests: stats.requests,
        inputTokens: stats.inputTokens,
        outputTokens: stats.outputTokens,
        cacheCreateTokens: stats.cacheCreateTokens,
        cacheReadTokens: stats.cacheReadTokens,
        allTokens: stats.allTokens,
        // 添加费用信息
        costs: costData.costs,
        formatted: costData.formatted,
        pricing: costData.pricing,
        usingDynamicPricing: costData.usingDynamicPricing
      })
    }

    // 如果没有找到模型级别的详细数据，尝试从汇总数据中生成展示
    if (modelStats.length === 0) {
      logger.info(
        `📊 No detailed model stats found, trying to get aggregate data for API key ${keyId}`
      )

      // 尝试从API Keys列表中获取usage数据作为备选方案
      try {
        const apiKeys = await apiKeyService.getAllApiKeys()
        const targetApiKey = apiKeys.find((key) => key.id === keyId)

        if (targetApiKey && targetApiKey.usage) {
          logger.info(
            `📊 Found API key usage data from getAllApiKeys for ${keyId}:`,
            targetApiKey.usage
          )

          // 从汇总数据创建展示条目
          let usageData
          if (period === 'custom' || period === 'daily') {
            // 对于自定义或日统计，使用daily数据或total数据
            usageData = targetApiKey.usage.daily || targetApiKey.usage.total
          } else {
            // 对于月统计，使用monthly数据或total数据
            usageData = targetApiKey.usage.monthly || targetApiKey.usage.total
          }

          if (usageData && usageData.allTokens > 0) {
            const usage = {
              input_tokens: usageData.inputTokens || 0,
              output_tokens: usageData.outputTokens || 0,
              cache_creation_input_tokens: usageData.cacheCreateTokens || 0,
              cache_read_input_tokens: usageData.cacheReadTokens || 0
            }

            // 对于汇总数据，使用默认模型计算费用
            const costData = CostCalculator.calculateCost(usage, 'claude-3-5-sonnet-20241022')

            modelStats.push({
              model: '总体使用 (历史数据)',
              requests: usageData.requests || 0,
              inputTokens: usageData.inputTokens || 0,
              outputTokens: usageData.outputTokens || 0,
              cacheCreateTokens: usageData.cacheCreateTokens || 0,
              cacheReadTokens: usageData.cacheReadTokens || 0,
              allTokens: usageData.allTokens || 0,
              // 添加费用信息
              costs: costData.costs,
              formatted: costData.formatted,
              pricing: costData.pricing,
              usingDynamicPricing: costData.usingDynamicPricing
            })

            logger.info('📊 Generated display data from API key usage stats')
          } else {
            logger.info(`📊 No usage data found for period ${period} in API key data`)
          }
        } else {
          logger.info(`📊 API key ${keyId} not found or has no usage data`)
        }
      } catch (error) {
        logger.error('❌ Error fetching API key usage data:', error)
      }
    }

    // 按总token数降序排列
    modelStats.sort((a, b) => b.allTokens - a.allTokens)

    logger.info(`📊 Returning ${modelStats.length} model stats for API key ${keyId}:`, modelStats)

    return res.json({ success: true, data: modelStats })
  } catch (error) {
    logger.error('❌ Failed to get API key model stats:', error)
    return res
      .status(500)
      .json({ error: 'Failed to get API key model stats', message: error.message })
  }
})

// 获取按账号分组的使用趋势
router.get('/account-usage-trend', authenticateAdmin, async (req, res) => {
  try {
    const { granularity = 'day', group = 'claude', days = 7, startDate, endDate } = req.query

    const allowedGroups = ['claude', 'openai', 'gemini', 'droid']
    if (!allowedGroups.includes(group)) {
      return res.status(400).json({
        success: false,
        error: 'Invalid account group'
      })
    }

    const groupLabels = {
      claude: 'Claude账户',
      openai: 'OpenAI账户',
      gemini: 'Gemini账户',
      droid: 'Droid账户'
    }

    // 拉取各平台账号列表
    let accounts = []
    if (group === 'claude') {
      const [claudeAccounts, claudeConsoleAccounts] = await Promise.all([
        claudeAccountService.getAllAccounts(),
        claudeConsoleAccountService.getAllAccounts()
      ])

      accounts = [
        ...claudeAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || account.email || `Claude账号 ${shortId}`,
            platform: 'claude'
          }
        }),
        ...claudeConsoleAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || `Console账号 ${shortId}`,
            platform: 'claude-console'
          }
        })
      ]
    } else if (group === 'openai') {
      const [openaiAccounts, openaiResponsesAccounts] = await Promise.all([
        openaiAccountService.getAllAccounts(),
        openaiResponsesAccountService.getAllAccounts(true)
      ])

      accounts = [
        ...openaiAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || account.email || `OpenAI账号 ${shortId}`,
            platform: 'openai'
          }
        }),
        ...openaiResponsesAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || `Responses账号 ${shortId}`,
            platform: 'openai-responses'
          }
        })
      ]
    } else if (group === 'gemini') {
      const [geminiAccounts, geminiApiAccounts] = await Promise.all([
        geminiAccountService.getAllAccounts(),
        geminiApiAccountService.getAllAccounts(true)
      ])

      accounts = [
        ...geminiAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || account.email || `Gemini账号 ${shortId}`,
            platform: 'gemini'
          }
        }),
        ...geminiApiAccounts.map((account) => {
          const id = String(account.id || '')
          const shortId = id ? id.slice(0, 8) : '未知'
          return {
            id,
            name: account.name || `Gemini-API账号 ${shortId}`,
            platform: 'gemini-api'
          }
        })
      ]
    } else if (group === 'droid') {
      const droidAccounts = await droidAccountService.getAllAccounts()
      accounts = droidAccounts.map((account) => {
        const id = String(account.id || '')
        const shortId = id ? id.slice(0, 8) : '未知'
        return {
          id,
          name: account.name || account.ownerEmail || account.ownerName || `Droid账号 ${shortId}`,
          platform: 'droid'
        }
      })
    }

    if (!accounts || accounts.length === 0) {
      return res.json({
        success: true,
        data: [],
        granularity,
        group,
        groupLabel: groupLabels[group],
        topAccounts: [],
        totalAccounts: 0
      })
    }

    const accountMap = new Map()
    const accountIdSet = new Set()
    for (const account of accounts) {
      accountMap.set(account.id, {
        name: account.name,
        platform: account.platform
      })
      accountIdSet.add(account.id)
    }

    const fallbackModelByGroup = {
      claude: 'claude-3-5-sonnet-20241022',
      openai: 'gpt-4o-mini-2024-07-18',
      gemini: 'gemini-1.5-flash'
    }
    const fallbackModel = fallbackModelByGroup[group] || 'unknown'

    const client = redis.getClientSafe()
    const trendData = []
    const accountCostTotals = new Map()

    const sumModelCosts = async (accountId, period, timeKey) => {
      const modelPattern = `account_usage:model:${period}:${accountId}:*:${timeKey}`
      const modelKeys = await client.keys(modelPattern)
      let totalCost = 0

      for (const modelKey of modelKeys) {
        const modelData = await client.hgetall(modelKey)
        if (!modelData) {
          continue
        }

        const parts = modelKey.split(':')
        if (parts.length < 5) {
          continue
        }

        const modelName = parts[4]
        const usage = {
          input_tokens: parseInt(modelData.inputTokens) || 0,
          output_tokens: parseInt(modelData.outputTokens) || 0,
          cache_creation_input_tokens: parseInt(modelData.cacheCreateTokens) || 0,
          cache_read_input_tokens: parseInt(modelData.cacheReadTokens) || 0
        }

        const costResult = CostCalculator.calculateCost(usage, modelName)
        totalCost += costResult.costs.total
      }

      return totalCost
    }

    if (granularity === 'hour') {
      let startTime
      let endTime

      if (startDate && endDate) {
        startTime = new Date(startDate)
        endTime = new Date(endDate)
      } else {
        endTime = new Date()
        startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000)
      }

      const currentHour = new Date(startTime)
      currentHour.setMinutes(0, 0, 0)

      while (currentHour <= endTime) {
        const tzCurrentHour = redis.getDateInTimezone(currentHour)
        const dateStr = redis.getDateStringInTimezone(currentHour)
        const hour = String(tzCurrentHour.getUTCHours()).padStart(2, '0')
        const hourKey = `${dateStr}:${hour}`

        const tzDateForLabel = redis.getDateInTimezone(currentHour)
        const monthLabel = String(tzDateForLabel.getUTCMonth() + 1).padStart(2, '0')
        const dayLabel = String(tzDateForLabel.getUTCDate()).padStart(2, '0')
        const hourLabel = String(tzDateForLabel.getUTCHours()).padStart(2, '0')

        const hourData = {
          hour: currentHour.toISOString(),
          label: `${monthLabel}/${dayLabel} ${hourLabel}:00`,
          accounts: {}
        }

        const pattern = `account_usage:hourly:*:${hourKey}`
        const keys = await client.keys(pattern)

        for (const key of keys) {
          const match = key.match(/account_usage:hourly:(.+?):\d{4}-\d{2}-\d{2}:\d{2}/)
          if (!match) {
            continue
          }

          const accountId = match[1]
          if (!accountIdSet.has(accountId)) {
            continue
          }

          const data = await client.hgetall(key)
          if (!data) {
            continue
          }

          const inputTokens = parseInt(data.inputTokens) || 0
          const outputTokens = parseInt(data.outputTokens) || 0
          const cacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
          const cacheReadTokens = parseInt(data.cacheReadTokens) || 0
          const allTokens =
            parseInt(data.allTokens) ||
            inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens
          const requests = parseInt(data.requests) || 0

          let cost = await sumModelCosts(accountId, 'hourly', hourKey)

          if (cost === 0 && allTokens > 0) {
            const fallbackUsage = {
              input_tokens: inputTokens,
              output_tokens: outputTokens,
              cache_creation_input_tokens: cacheCreateTokens,
              cache_read_input_tokens: cacheReadTokens
            }
            const fallbackResult = CostCalculator.calculateCost(fallbackUsage, fallbackModel)
            cost = fallbackResult.costs.total
          }

          const formattedCost = CostCalculator.formatCost(cost)
          const accountInfo = accountMap.get(accountId)

          hourData.accounts[accountId] = {
            name: accountInfo ? accountInfo.name : `账号 ${accountId.slice(0, 8)}`,
            cost,
            formattedCost,
            requests
          }

          accountCostTotals.set(accountId, (accountCostTotals.get(accountId) || 0) + cost)
        }

        trendData.push(hourData)
        currentHour.setHours(currentHour.getHours() + 1)
      }
    } else {
      const daysCount = parseInt(days) || 7
      const today = new Date()

      for (let i = 0; i < daysCount; i++) {
        const date = new Date(today)
        date.setDate(date.getDate() - i)
        const dateStr = redis.getDateStringInTimezone(date)

        const dayData = {
          date: dateStr,
          accounts: {}
        }

        const pattern = `account_usage:daily:*:${dateStr}`
        const keys = await client.keys(pattern)

        for (const key of keys) {
          const match = key.match(/account_usage:daily:(.+?):\d{4}-\d{2}-\d{2}/)
          if (!match) {
            continue
          }

          const accountId = match[1]
          if (!accountIdSet.has(accountId)) {
            continue
          }

          const data = await client.hgetall(key)
          if (!data) {
            continue
          }

          const inputTokens = parseInt(data.inputTokens) || 0
          const outputTokens = parseInt(data.outputTokens) || 0
          const cacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
          const cacheReadTokens = parseInt(data.cacheReadTokens) || 0
          const allTokens =
            parseInt(data.allTokens) ||
            inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens
          const requests = parseInt(data.requests) || 0

          let cost = await sumModelCosts(accountId, 'daily', dateStr)

          if (cost === 0 && allTokens > 0) {
            const fallbackUsage = {
              input_tokens: inputTokens,
              output_tokens: outputTokens,
              cache_creation_input_tokens: cacheCreateTokens,
              cache_read_input_tokens: cacheReadTokens
            }
            const fallbackResult = CostCalculator.calculateCost(fallbackUsage, fallbackModel)
            cost = fallbackResult.costs.total
          }

          const formattedCost = CostCalculator.formatCost(cost)
          const accountInfo = accountMap.get(accountId)

          dayData.accounts[accountId] = {
            name: accountInfo ? accountInfo.name : `账号 ${accountId.slice(0, 8)}`,
            cost,
            formattedCost,
            requests
          }

          accountCostTotals.set(accountId, (accountCostTotals.get(accountId) || 0) + cost)
        }

        trendData.push(dayData)
      }
    }

    if (granularity === 'hour') {
      trendData.sort((a, b) => new Date(a.hour) - new Date(b.hour))
    } else {
      trendData.sort((a, b) => new Date(a.date) - new Date(b.date))
    }

    const topAccounts = Array.from(accountCostTotals.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, 20)
      .map(([accountId]) => accountId)

    return res.json({
      success: true,
      data: trendData,
      granularity,
      group,
      groupLabel: groupLabels[group],
      topAccounts,
      totalAccounts: accountCostTotals.size
    })
  } catch (error) {
    logger.error('❌ Failed to get account usage trend:', error)
    return res
      .status(500)
      .json({ error: 'Failed to get account usage trend', message: error.message })
  }
})

// 获取按API Key分组的使用趋势
router.get('/api-keys-usage-trend', authenticateAdmin, async (req, res) => {
  try {
    const { granularity = 'day', days = 7, startDate, endDate } = req.query

    logger.info(`📊 Getting API keys usage trend, granularity: ${granularity}, days: ${days}`)

    const client = redis.getClientSafe()
    const trendData = []

    // 获取所有API Keys
    const apiKeys = await apiKeyService.getAllApiKeys()
    const apiKeyMap = new Map(apiKeys.map((key) => [key.id, key]))

    if (granularity === 'hour') {
      // 小时粒度统计
      let endTime, startTime

      if (startDate && endDate) {
        // 自定义时间范围
        startTime = new Date(startDate)
        endTime = new Date(endDate)
      } else {
        // 默认近24小时
        endTime = new Date()
        startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000)
      }

      // 按小时遍历
      const currentHour = new Date(startTime)
      currentHour.setMinutes(0, 0, 0)

      while (currentHour <= endTime) {
        // 使用时区转换后的时间来生成键
        const tzCurrentHour = redis.getDateInTimezone(currentHour)
        const dateStr = redis.getDateStringInTimezone(currentHour)
        const hour = String(tzCurrentHour.getUTCHours()).padStart(2, '0')
        const hourKey = `${dateStr}:${hour}`

        // 获取这个小时所有API Key的数据
        const pattern = `usage:hourly:*:${hourKey}`
        const keys = await client.keys(pattern)

        // 格式化时间标签
        const tzDateForLabel = redis.getDateInTimezone(currentHour)
        const monthLabel = String(tzDateForLabel.getUTCMonth() + 1).padStart(2, '0')
        const dayLabel = String(tzDateForLabel.getUTCDate()).padStart(2, '0')
        const hourLabel = String(tzDateForLabel.getUTCHours()).padStart(2, '0')

        const hourData = {
          hour: currentHour.toISOString(), // 使用原始时间，不进行时区转换
          label: `${monthLabel}/${dayLabel} ${hourLabel}:00`, // 添加格式化的标签
          apiKeys: {}
        }

        // 先收集基础数据
        const apiKeyDataMap = new Map()
        for (const key of keys) {
          const match = key.match(/usage:hourly:(.+?):\d{4}-\d{2}-\d{2}:\d{2}/)
          if (!match) {
            continue
          }

          const apiKeyId = match[1]
          const data = await client.hgetall(key)

          if (data && apiKeyMap.has(apiKeyId)) {
            const inputTokens = parseInt(data.inputTokens) || 0
            const outputTokens = parseInt(data.outputTokens) || 0
            const cacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
            const cacheReadTokens = parseInt(data.cacheReadTokens) || 0
            const totalTokens = inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens

            apiKeyDataMap.set(apiKeyId, {
              name: apiKeyMap.get(apiKeyId).name,
              tokens: totalTokens,
              requests: parseInt(data.requests) || 0,
              inputTokens,
              outputTokens,
              cacheCreateTokens,
              cacheReadTokens
            })
          }
        }

        // 获取该小时的模型级别数据来计算准确费用
        const modelPattern = `usage:*:model:hourly:*:${hourKey}`
        const modelKeys = await client.keys(modelPattern)
        const apiKeyCostMap = new Map()

        for (const modelKey of modelKeys) {
          const match = modelKey.match(/usage:(.+?):model:hourly:(.+?):\d{4}-\d{2}-\d{2}:\d{2}/)
          if (!match) {
            continue
          }

          const apiKeyId = match[1]
          const model = match[2]
          const modelData = await client.hgetall(modelKey)

          if (modelData && apiKeyDataMap.has(apiKeyId)) {
            const usage = {
              input_tokens: parseInt(modelData.inputTokens) || 0,
              output_tokens: parseInt(modelData.outputTokens) || 0,
              cache_creation_input_tokens: parseInt(modelData.cacheCreateTokens) || 0,
              cache_read_input_tokens: parseInt(modelData.cacheReadTokens) || 0
            }

            const costResult = CostCalculator.calculateCost(usage, model)
            const currentCost = apiKeyCostMap.get(apiKeyId) || 0
            apiKeyCostMap.set(apiKeyId, currentCost + costResult.costs.total)
          }
        }

        // 组合数据
        for (const [apiKeyId, data] of apiKeyDataMap) {
          const cost = apiKeyCostMap.get(apiKeyId) || 0

          // 如果没有模型级别数据，使用默认模型计算（降级方案）
          let finalCost = cost
          let formattedCost = CostCalculator.formatCost(cost)

          if (cost === 0 && data.tokens > 0) {
            const usage = {
              input_tokens: data.inputTokens,
              output_tokens: data.outputTokens,
              cache_creation_input_tokens: data.cacheCreateTokens,
              cache_read_input_tokens: data.cacheReadTokens
            }
            const fallbackResult = CostCalculator.calculateCost(usage, 'claude-3-5-sonnet-20241022')
            finalCost = fallbackResult.costs.total
            formattedCost = fallbackResult.formatted.total
          }

          hourData.apiKeys[apiKeyId] = {
            name: data.name,
            tokens: data.tokens,
            requests: data.requests,
            cost: finalCost,
            formattedCost
          }
        }

        trendData.push(hourData)
        currentHour.setHours(currentHour.getHours() + 1)
      }
    } else {
      // 天粒度统计
      const daysCount = parseInt(days) || 7
      const today = new Date()

      // 获取过去N天的数据
      for (let i = 0; i < daysCount; i++) {
        const date = new Date(today)
        date.setDate(date.getDate() - i)
        const dateStr = redis.getDateStringInTimezone(date)

        // 获取这一天所有API Key的数据
        const pattern = `usage:daily:*:${dateStr}`
        const keys = await client.keys(pattern)

        const dayData = {
          date: dateStr,
          apiKeys: {}
        }

        // 先收集基础数据
        const apiKeyDataMap = new Map()
        for (const key of keys) {
          const match = key.match(/usage:daily:(.+?):\d{4}-\d{2}-\d{2}/)
          if (!match) {
            continue
          }

          const apiKeyId = match[1]
          const data = await client.hgetall(key)

          if (data && apiKeyMap.has(apiKeyId)) {
            const inputTokens = parseInt(data.inputTokens) || 0
            const outputTokens = parseInt(data.outputTokens) || 0
            const cacheCreateTokens = parseInt(data.cacheCreateTokens) || 0
            const cacheReadTokens = parseInt(data.cacheReadTokens) || 0
            const totalTokens = inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens

            apiKeyDataMap.set(apiKeyId, {
              name: apiKeyMap.get(apiKeyId).name,
              tokens: totalTokens,
              requests: parseInt(data.requests) || 0,
              inputTokens,
              outputTokens,
              cacheCreateTokens,
              cacheReadTokens
            })
          }
        }

        // 获取该天的模型级别数据来计算准确费用
        const modelPattern = `usage:*:model:daily:*:${dateStr}`
        const modelKeys = await client.keys(modelPattern)
        const apiKeyCostMap = new Map()

        for (const modelKey of modelKeys) {
          const match = modelKey.match(/usage:(.+?):model:daily:(.+?):\d{4}-\d{2}-\d{2}/)
          if (!match) {
            continue
          }

          const apiKeyId = match[1]
          const model = match[2]
          const modelData = await client.hgetall(modelKey)

          if (modelData && apiKeyDataMap.has(apiKeyId)) {
            const usage = {
              input_tokens: parseInt(modelData.inputTokens) || 0,
              output_tokens: parseInt(modelData.outputTokens) || 0,
              cache_creation_input_tokens: parseInt(modelData.cacheCreateTokens) || 0,
              cache_read_input_tokens: parseInt(modelData.cacheReadTokens) || 0
            }

            const costResult = CostCalculator.calculateCost(usage, model)
            const currentCost = apiKeyCostMap.get(apiKeyId) || 0
            apiKeyCostMap.set(apiKeyId, currentCost + costResult.costs.total)
          }
        }

        // 组合数据
        for (const [apiKeyId, data] of apiKeyDataMap) {
          const cost = apiKeyCostMap.get(apiKeyId) || 0

          // 如果没有模型级别数据，使用默认模型计算（降级方案）
          let finalCost = cost
          let formattedCost = CostCalculator.formatCost(cost)

          if (cost === 0 && data.tokens > 0) {
            const usage = {
              input_tokens: data.inputTokens,
              output_tokens: data.outputTokens,
              cache_creation_input_tokens: data.cacheCreateTokens,
              cache_read_input_tokens: data.cacheReadTokens
            }
            const fallbackResult = CostCalculator.calculateCost(usage, 'claude-3-5-sonnet-20241022')
            finalCost = fallbackResult.costs.total
            formattedCost = fallbackResult.formatted.total
          }

          dayData.apiKeys[apiKeyId] = {
            name: data.name,
            tokens: data.tokens,
            requests: data.requests,
            cost: finalCost,
            formattedCost
          }
        }

        trendData.push(dayData)
      }
    }

    // 按时间正序排列
    if (granularity === 'hour') {
      trendData.sort((a, b) => new Date(a.hour) - new Date(b.hour))
    } else {
      trendData.sort((a, b) => new Date(a.date) - new Date(b.date))
    }

    // 计算每个API Key的总token数，用于排序
    const apiKeyTotals = new Map()
    for (const point of trendData) {
      for (const [apiKeyId, data] of Object.entries(point.apiKeys)) {
        apiKeyTotals.set(apiKeyId, (apiKeyTotals.get(apiKeyId) || 0) + data.tokens)
      }
    }

    // 获取前10个使用量最多的API Key
    const topApiKeys = Array.from(apiKeyTotals.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, 10)
      .map(([apiKeyId]) => apiKeyId)

    return res.json({
      success: true,
      data: trendData,
      granularity,
      topApiKeys,
      totalApiKeys: apiKeyTotals.size
    })
  } catch (error) {
    logger.error('❌ Failed to get API keys usage trend:', error)
    return res
      .status(500)
      .json({ error: 'Failed to get API keys usage trend', message: error.message })
  }
})

// 计算总体使用费用
router.get('/usage-costs', authenticateAdmin, async (req, res) => {
  try {
    const { period = 'all' } = req.query // all, today, monthly, 7days

    logger.info(`💰 Calculating usage costs for period: ${period}`)

    // 模型名标准化函数（与redis.js保持一致）
    const normalizeModelName = (model) => {
      if (!model || model === 'unknown') {
        return model
      }

      // 对于Bedrock模型，去掉区域前缀进行统一
      if (model.includes('.anthropic.') || model.includes('.claude')) {
        // 匹配所有AWS区域格式：region.anthropic.model-name-v1:0 -> claude-model-name
        // 支持所有AWS区域格式，如：us-east-1, eu-west-1, ap-southeast-1, ca-central-1等
        let normalized = model.replace(/^[a-z0-9-]+\./, '') // 去掉任何区域前缀（更通用）
        normalized = normalized.replace('anthropic.', '') // 去掉anthropic前缀
        normalized = normalized.replace(/-v\d+:\d+$/, '') // 去掉版本后缀（如-v1:0, -v2:1等）
        return normalized
      }

      // 对于其他模型，去掉常见的版本后缀
      return model.replace(/-v\d+:\d+$|:latest$/, '')
    }

    // 获取所有API Keys的使用统计
    const apiKeys = await apiKeyService.getAllApiKeys()

    const totalCosts = {
      inputCost: 0,
      outputCost: 0,
      cacheCreateCost: 0,
      cacheReadCost: 0,
      totalCost: 0
    }

    const modelCosts = {}

    // 按模型统计费用
    const client = redis.getClientSafe()
    const today = redis.getDateStringInTimezone()
    const tzDate = redis.getDateInTimezone()
    const currentMonth = `${tzDate.getUTCFullYear()}-${String(tzDate.getUTCMonth() + 1).padStart(
      2,
      '0'
    )}`

    let pattern
    if (period === 'today') {
      pattern = `usage:model:daily:*:${today}`
    } else if (period === 'monthly') {
      pattern = `usage:model:monthly:*:${currentMonth}`
    } else if (period === '7days') {
      // 最近7天：汇总daily数据
      const modelUsageMap = new Map()

      // 获取最近7天的所有daily统计数据
      for (let i = 0; i < 7; i++) {
        const date = new Date()
        date.setDate(date.getDate() - i)
        const currentTzDate = redis.getDateInTimezone(date)
        const dateStr = `${currentTzDate.getUTCFullYear()}-${String(
          currentTzDate.getUTCMonth() + 1
        ).padStart(2, '0')}-${String(currentTzDate.getUTCDate()).padStart(2, '0')}`
        const dayPattern = `usage:model:daily:*:${dateStr}`

        const dayKeys = await client.keys(dayPattern)

        for (const key of dayKeys) {
          const modelMatch = key.match(/usage:model:daily:(.+):\d{4}-\d{2}-\d{2}$/)
          if (!modelMatch) {
            continue
          }

          const rawModel = modelMatch[1]
          const normalizedModel = normalizeModelName(rawModel)
          const data = await client.hgetall(key)

          if (data && Object.keys(data).length > 0) {
            if (!modelUsageMap.has(normalizedModel)) {
              modelUsageMap.set(normalizedModel, {
                inputTokens: 0,
                outputTokens: 0,
                cacheCreateTokens: 0,
                cacheReadTokens: 0
              })
            }

            const modelUsage = modelUsageMap.get(normalizedModel)
            modelUsage.inputTokens += parseInt(data.inputTokens) || 0
            modelUsage.outputTokens += parseInt(data.outputTokens) || 0
            modelUsage.cacheCreateTokens += parseInt(data.cacheCreateTokens) || 0
            modelUsage.cacheReadTokens += parseInt(data.cacheReadTokens) || 0
          }
        }
      }

      // 计算7天统计的费用
      logger.info(`💰 Processing ${modelUsageMap.size} unique models for 7days cost calculation`)

      for (const [model, usage] of modelUsageMap) {
        const usageData = {
          input_tokens: usage.inputTokens,
          output_tokens: usage.outputTokens,
          cache_creation_input_tokens: usage.cacheCreateTokens,
          cache_read_input_tokens: usage.cacheReadTokens
        }

        const costResult = CostCalculator.calculateCost(usageData, model)
        totalCosts.inputCost += costResult.costs.input
        totalCosts.outputCost += costResult.costs.output
        totalCosts.cacheCreateCost += costResult.costs.cacheWrite
        totalCosts.cacheReadCost += costResult.costs.cacheRead
        totalCosts.totalCost += costResult.costs.total

        logger.info(
          `💰 Model ${model} (7days): ${
            usage.inputTokens + usage.outputTokens + usage.cacheCreateTokens + usage.cacheReadTokens
          } tokens, cost: ${costResult.formatted.total}`
        )

        // 记录模型费用
        modelCosts[model] = {
          model,
          requests: 0, // 7天汇总数据没有请求数统计
          usage: usageData,
          costs: costResult.costs,
          formatted: costResult.formatted,
          usingDynamicPricing: costResult.usingDynamicPricing
        }
      }

      // 返回7天统计结果
      return res.json({
        success: true,
        data: {
          period,
          totalCosts: {
            ...totalCosts,
            formatted: {
              inputCost: CostCalculator.formatCost(totalCosts.inputCost),
              outputCost: CostCalculator.formatCost(totalCosts.outputCost),
              cacheCreateCost: CostCalculator.formatCost(totalCosts.cacheCreateCost),
              cacheReadCost: CostCalculator.formatCost(totalCosts.cacheReadCost),
              totalCost: CostCalculator.formatCost(totalCosts.totalCost)
            }
          },
          modelCosts: Object.values(modelCosts)
        }
      })
    } else {
      // 全部时间，先尝试从Redis获取所有历史模型统计数据（只使用monthly数据避免重复计算）
      const allModelKeys = await client.keys('usage:model:monthly:*:*')
      logger.info(`💰 Total period calculation: found ${allModelKeys.length} monthly model keys`)

      if (allModelKeys.length > 0) {
        // 如果有详细的模型统计数据，使用模型级别的计算
        const modelUsageMap = new Map()

        for (const key of allModelKeys) {
          // 解析模型名称（只处理monthly数据）
          const modelMatch = key.match(/usage:model:monthly:(.+):(\d{4}-\d{2})$/)
          if (!modelMatch) {
            continue
          }

          const model = modelMatch[1]
          const data = await client.hgetall(key)

          if (data && Object.keys(data).length > 0) {
            if (!modelUsageMap.has(model)) {
              modelUsageMap.set(model, {
                inputTokens: 0,
                outputTokens: 0,
                cacheCreateTokens: 0,
                cacheReadTokens: 0
              })
            }

            const modelUsage = modelUsageMap.get(model)
            modelUsage.inputTokens += parseInt(data.inputTokens) || 0
            modelUsage.outputTokens += parseInt(data.outputTokens) || 0
            modelUsage.cacheCreateTokens += parseInt(data.cacheCreateTokens) || 0
            modelUsage.cacheReadTokens += parseInt(data.cacheReadTokens) || 0
          }
        }

        // 使用模型级别的数据计算费用
        logger.info(`💰 Processing ${modelUsageMap.size} unique models for total cost calculation`)

        for (const [model, usage] of modelUsageMap) {
          const usageData = {
            input_tokens: usage.inputTokens,
            output_tokens: usage.outputTokens,
            cache_creation_input_tokens: usage.cacheCreateTokens,
            cache_read_input_tokens: usage.cacheReadTokens
          }

          const costResult = CostCalculator.calculateCost(usageData, model)
          totalCosts.inputCost += costResult.costs.input
          totalCosts.outputCost += costResult.costs.output
          totalCosts.cacheCreateCost += costResult.costs.cacheWrite
          totalCosts.cacheReadCost += costResult.costs.cacheRead
          totalCosts.totalCost += costResult.costs.total

          logger.info(
            `💰 Model ${model}: ${
              usage.inputTokens +
              usage.outputTokens +
              usage.cacheCreateTokens +
              usage.cacheReadTokens
            } tokens, cost: ${costResult.formatted.total}`
          )

          // 记录模型费用
          modelCosts[model] = {
            model,
            requests: 0, // 历史汇总数据没有请求数
            usage: usageData,
            costs: costResult.costs,
            formatted: costResult.formatted,
            usingDynamicPricing: costResult.usingDynamicPricing
          }
        }
      } else {
        // 如果没有详细的模型统计数据，回退到API Key汇总数据
        logger.warn('No detailed model statistics found, falling back to API Key aggregated data')

        for (const apiKey of apiKeys) {
          if (apiKey.usage && apiKey.usage.total) {
            const usage = {
              input_tokens: apiKey.usage.total.inputTokens || 0,
              output_tokens: apiKey.usage.total.outputTokens || 0,
              cache_creation_input_tokens: apiKey.usage.total.cacheCreateTokens || 0,
              cache_read_input_tokens: apiKey.usage.total.cacheReadTokens || 0
            }

            // 使用加权平均价格计算（基于当前活跃模型的价格分布）
            const costResult = CostCalculator.calculateCost(usage, 'claude-3-5-haiku-20241022')
            totalCosts.inputCost += costResult.costs.input
            totalCosts.outputCost += costResult.costs.output
            totalCosts.cacheCreateCost += costResult.costs.cacheWrite
            totalCosts.cacheReadCost += costResult.costs.cacheRead
            totalCosts.totalCost += costResult.costs.total
          }
        }
      }

      return res.json({
        success: true,
        data: {
          period,
          totalCosts: {
            ...totalCosts,
            formatted: {
              inputCost: CostCalculator.formatCost(totalCosts.inputCost),
              outputCost: CostCalculator.formatCost(totalCosts.outputCost),
              cacheCreateCost: CostCalculator.formatCost(totalCosts.cacheCreateCost),
              cacheReadCost: CostCalculator.formatCost(totalCosts.cacheReadCost),
              totalCost: CostCalculator.formatCost(totalCosts.totalCost)
            }
          },
          modelCosts: Object.values(modelCosts).sort((a, b) => b.costs.total - a.costs.total),
          pricingServiceStatus: pricingService.getStatus()
        }
      })
    }

    // 对于今日或本月，从Redis获取详细的模型统计
    const keys = await client.keys(pattern)

    for (const key of keys) {
      const match = key.match(
        period === 'today'
          ? /usage:model:daily:(.+):\d{4}-\d{2}-\d{2}$/
          : /usage:model:monthly:(.+):\d{4}-\d{2}$/
      )

      if (!match) {
        continue
      }

      const model = match[1]
      const data = await client.hgetall(key)

      if (data && Object.keys(data).length > 0) {
        const usage = {
          input_tokens: parseInt(data.inputTokens) || 0,
          output_tokens: parseInt(data.outputTokens) || 0,
          cache_creation_input_tokens: parseInt(data.cacheCreateTokens) || 0,
          cache_read_input_tokens: parseInt(data.cacheReadTokens) || 0
        }

        const costResult = CostCalculator.calculateCost(usage, model)

        // 累加总费用
        totalCosts.inputCost += costResult.costs.input
        totalCosts.outputCost += costResult.costs.output
        totalCosts.cacheCreateCost += costResult.costs.cacheWrite
        totalCosts.cacheReadCost += costResult.costs.cacheRead
        totalCosts.totalCost += costResult.costs.total

        // 记录模型费用
        modelCosts[model] = {
          model,
          requests: parseInt(data.requests) || 0,
          usage,
          costs: costResult.costs,
          formatted: costResult.formatted,
          usingDynamicPricing: costResult.usingDynamicPricing
        }
      }
    }

    return res.json({
      success: true,
      data: {
        period,
        totalCosts: {
          ...totalCosts,
          formatted: {
            inputCost: CostCalculator.formatCost(totalCosts.inputCost),
            outputCost: CostCalculator.formatCost(totalCosts.outputCost),
            cacheCreateCost: CostCalculator.formatCost(totalCosts.cacheCreateCost),
            cacheReadCost: CostCalculator.formatCost(totalCosts.cacheReadCost),
            totalCost: CostCalculator.formatCost(totalCosts.totalCost)
          }
        },
        modelCosts: Object.values(modelCosts).sort((a, b) => b.costs.total - a.costs.total),
        pricingServiceStatus: pricingService.getStatus()
      }
    })
  } catch (error) {
    logger.error('❌ Failed to calculate usage costs:', error)
    return res
      .status(500)
      .json({ error: 'Failed to calculate usage costs', message: error.message })
  }
})

// 获取 API Key 的请求记录时间线
router.get('/api-keys/:keyId/usage-records', authenticateAdmin, async (req, res) => {
  try {
    const { keyId } = req.params
    const {
      page = 1,
      pageSize = 50,
      startDate,
      endDate,
      model,
      accountId,
      sortOrder = 'desc'
    } = req.query

    const pageNumber = Math.max(parseInt(page, 10) || 1, 1)
    const pageSizeNumber = Math.min(Math.max(parseInt(pageSize, 10) || 50, 1), 200)
    const normalizedSortOrder = sortOrder === 'asc' ? 'asc' : 'desc'

    const startTime = startDate ? new Date(startDate) : null
    const endTime = endDate ? new Date(endDate) : null

    if (
      (startDate && Number.isNaN(startTime?.getTime())) ||
      (endDate && Number.isNaN(endTime?.getTime()))
    ) {
      return res.status(400).json({ success: false, error: 'Invalid date range' })
    }

    if (startTime && endTime && startTime > endTime) {
      return res
        .status(400)
        .json({ success: false, error: 'Start date must be before or equal to end date' })
    }

    const apiKeyInfo = await redis.getApiKey(keyId)
    if (!apiKeyInfo || Object.keys(apiKeyInfo).length === 0) {
      return res.status(404).json({ success: false, error: 'API key not found' })
    }

    const rawRecords = await redis.getUsageRecords(keyId, 5000)

    const accountServices = [
      { type: 'claude', getter: (id) => claudeAccountService.getAccount(id) },
      { type: 'claude-console', getter: (id) => claudeConsoleAccountService.getAccount(id) },
      { type: 'ccr', getter: (id) => ccrAccountService.getAccount(id) },
      { type: 'openai', getter: (id) => openaiAccountService.getAccount(id) },
      { type: 'openai-responses', getter: (id) => openaiResponsesAccountService.getAccount(id) },
      { type: 'gemini', getter: (id) => geminiAccountService.getAccount(id) },
      { type: 'gemini-api', getter: (id) => geminiApiAccountService.getAccount(id) },
      { type: 'droid', getter: (id) => droidAccountService.getAccount(id) }
    ]

    const accountCache = new Map()
    const resolveAccountInfo = async (id, type) => {
      if (!id) {
        return null
      }

      const cacheKey = `${type || 'any'}:${id}`
      if (accountCache.has(cacheKey)) {
        return accountCache.get(cacheKey)
      }

      let servicesToTry = type
        ? accountServices.filter((svc) => svc.type === type)
        : accountServices

      // 若渠道改名或传入未知类型，回退尝试全量服务，避免漏解析历史账号
      if (!servicesToTry.length) {
        servicesToTry = accountServices
      }

      for (const service of servicesToTry) {
        try {
          const account = await service.getter(id)
          if (account) {
            const info = {
              id,
              name: account.name || account.email || id,
              type: service.type,
              status: account.status || account.isActive
            }
            accountCache.set(cacheKey, info)
            return info
          }
        } catch (error) {
          logger.debug(`⚠️ Failed to resolve account ${id} via ${service.type}: ${error.message}`)
        }
      }

      accountCache.set(cacheKey, null)
      return null
    }

    const toUsageObject = (record) => ({
      input_tokens: record.inputTokens || 0,
      output_tokens: record.outputTokens || 0,
      cache_creation_input_tokens: record.cacheCreateTokens || 0,
      cache_read_input_tokens: record.cacheReadTokens || 0,
      cache_creation: record.cacheCreation || record.cache_creation || null
    })

    const withinRange = (record) => {
      if (!record.timestamp) {
        return false
      }
      const ts = new Date(record.timestamp)
      if (Number.isNaN(ts.getTime())) {
        return false
      }
      if (startTime && ts < startTime) {
        return false
      }
      if (endTime && ts > endTime) {
        return false
      }
      return true
    }

    const filteredRecords = rawRecords.filter((record) => {
      if (!withinRange(record)) {
        return false
      }
      if (model && record.model !== model) {
        return false
      }
      if (accountId && record.accountId !== accountId) {
        return false
      }
      return true
    })

    filteredRecords.sort((a, b) => {
      const aTime = new Date(a.timestamp).getTime()
      const bTime = new Date(b.timestamp).getTime()
      if (Number.isNaN(aTime) || Number.isNaN(bTime)) {
        return 0
      }
      return normalizedSortOrder === 'asc' ? aTime - bTime : bTime - aTime
    })

    const summary = {
      totalRequests: 0,
      inputTokens: 0,
      outputTokens: 0,
      cacheCreateTokens: 0,
      cacheReadTokens: 0,
      totalTokens: 0,
      totalCost: 0
    }

    const modelSet = new Set()
    const accountOptionMap = new Map()
    let earliestTimestamp = null
    let latestTimestamp = null

    for (const record of filteredRecords) {
      const usage = toUsageObject(record)
      const costData = CostCalculator.calculateCost(usage, record.model || 'unknown')
      const computedCost =
        typeof record.cost === 'number' ? record.cost : costData?.costs?.total || 0
      const totalTokens =
        record.totalTokens ||
        usage.input_tokens +
          usage.output_tokens +
          usage.cache_creation_input_tokens +
          usage.cache_read_input_tokens

      summary.totalRequests += 1
      summary.inputTokens += usage.input_tokens
      summary.outputTokens += usage.output_tokens
      summary.cacheCreateTokens += usage.cache_creation_input_tokens
      summary.cacheReadTokens += usage.cache_read_input_tokens
      summary.totalTokens += totalTokens
      summary.totalCost += computedCost

      if (record.model) {
        modelSet.add(record.model)
      }

      if (record.accountId) {
        const normalizedType = record.accountType || 'unknown'
        if (!accountOptionMap.has(record.accountId)) {
          accountOptionMap.set(record.accountId, {
            id: record.accountId,
            accountTypes: new Set([normalizedType])
          })
        } else {
          accountOptionMap.get(record.accountId).accountTypes.add(normalizedType)
        }
      }

      if (record.timestamp) {
        const ts = new Date(record.timestamp)
        if (!Number.isNaN(ts.getTime())) {
          if (!earliestTimestamp || ts < earliestTimestamp) {
            earliestTimestamp = ts
          }
          if (!latestTimestamp || ts > latestTimestamp) {
            latestTimestamp = ts
          }
        }
      }
    }

    const totalRecords = filteredRecords.length
    const totalPages = totalRecords > 0 ? Math.ceil(totalRecords / pageSizeNumber) : 0
    const safePage = totalPages > 0 ? Math.min(pageNumber, totalPages) : 1
    const startIndex = (safePage - 1) * pageSizeNumber
    const pageRecords =
      totalRecords === 0 ? [] : filteredRecords.slice(startIndex, startIndex + pageSizeNumber)

    const enrichedRecords = []
    for (const record of pageRecords) {
      const usage = toUsageObject(record)
      const costData = CostCalculator.calculateCost(usage, record.model || 'unknown')
      const computedCost =
        typeof record.cost === 'number' ? record.cost : costData?.costs?.total || 0
      const totalTokens =
        record.totalTokens ||
        usage.input_tokens +
          usage.output_tokens +
          usage.cache_creation_input_tokens +
          usage.cache_read_input_tokens

      const accountInfo = await resolveAccountInfo(record.accountId, record.accountType)
      const resolvedAccountType = accountInfo?.type || record.accountType || 'unknown'

      enrichedRecords.push({
        timestamp: record.timestamp,
        model: record.model || 'unknown',
        accountId: record.accountId || null,
        accountName: accountInfo?.name || null,
        accountStatus: accountInfo?.status ?? null,
        accountType: resolvedAccountType,
        accountTypeName: accountTypeNames[resolvedAccountType] || '未知渠道',
        inputTokens: usage.input_tokens,
        outputTokens: usage.output_tokens,
        cacheCreateTokens: usage.cache_creation_input_tokens,
        cacheReadTokens: usage.cache_read_input_tokens,
        ephemeral5mTokens: record.ephemeral5mTokens || 0,
        ephemeral1hTokens: record.ephemeral1hTokens || 0,
        totalTokens,
        isLongContextRequest: record.isLongContext || record.isLongContextRequest || false,
        cost: Number(computedCost.toFixed(6)),
        costFormatted:
          record.costFormatted ||
          costData?.formatted?.total ||
          CostCalculator.formatCost(computedCost),
        costBreakdown: record.costBreakdown || {
          input: costData?.costs?.input || 0,
          output: costData?.costs?.output || 0,
          cacheCreate: costData?.costs?.cacheWrite || 0,
          cacheRead: costData?.costs?.cacheRead || 0,
          total: costData?.costs?.total || computedCost
        },
        responseTime: record.responseTime || null
      })
    }

    const accountOptions = []
    for (const option of accountOptionMap.values()) {
      const types = Array.from(option.accountTypes || [])

      // 优先按历史出现的 accountType 解析，若失败则回退全量解析
      let resolvedInfo = null
      for (const type of types) {
        resolvedInfo = await resolveAccountInfo(option.id, type)
        if (resolvedInfo && resolvedInfo.name) {
          break
        }
      }
      if (!resolvedInfo) {
        resolvedInfo = await resolveAccountInfo(option.id)
      }

      const chosenType = resolvedInfo?.type || types[0] || 'unknown'
      const chosenTypeName = accountTypeNames[chosenType] || '未知渠道'

      if (!resolvedInfo) {
        logger.warn(`⚠️ 保留无法解析的账户筛选项: ${option.id}, types=${types.join(',') || 'none'}`)
      }

      accountOptions.push({
        id: option.id,
        name: resolvedInfo?.name || option.id,
        accountType: chosenType,
        accountTypeName: chosenTypeName,
        rawTypes: types
      })
    }

    return res.json({
      success: true,
      data: {
        records: enrichedRecords,
        pagination: {
          currentPage: safePage,
          pageSize: pageSizeNumber,
          totalRecords,
          totalPages,
          hasNextPage: totalPages > 0 && safePage < totalPages,
          hasPreviousPage: totalPages > 0 && safePage > 1
        },
        filters: {
          startDate: startTime ? startTime.toISOString() : null,
          endDate: endTime ? endTime.toISOString() : null,
          model: model || null,
          accountId: accountId || null,
          sortOrder: normalizedSortOrder
        },
        apiKeyInfo: {
          id: keyId,
          name: apiKeyInfo.name || apiKeyInfo.label || keyId
        },
        summary: {
          ...summary,
          totalCost: Number(summary.totalCost.toFixed(6)),
          avgCost:
            summary.totalRequests > 0
              ? Number((summary.totalCost / summary.totalRequests).toFixed(6))
              : 0
        },
        availableFilters: {
          models: Array.from(modelSet),
          accounts: accountOptions,
          dateRange: {
            earliest: earliestTimestamp ? earliestTimestamp.toISOString() : null,
            latest: latestTimestamp ? latestTimestamp.toISOString() : null
          }
        }
      }
    })
  } catch (error) {
    logger.error('❌ Failed to get API key usage records:', error)
    return res
      .status(500)
      .json({ error: 'Failed to get API key usage records', message: error.message })
  }
})

// 获取账户的请求记录时间线
router.get('/accounts/:accountId/usage-records', authenticateAdmin, async (req, res) => {
  try {
    const { accountId } = req.params
    const {
      platform,
      page = 1,
      pageSize = 50,
      startDate,
      endDate,
      model,
      apiKeyId,
      sortOrder = 'desc'
    } = req.query

    const pageNumber = Math.max(parseInt(page, 10) || 1, 1)
    const pageSizeNumber = Math.min(Math.max(parseInt(pageSize, 10) || 50, 1), 200)
    const normalizedSortOrder = sortOrder === 'asc' ? 'asc' : 'desc'

    const startTime = startDate ? new Date(startDate) : null
    const endTime = endDate ? new Date(endDate) : null

    if (
      (startDate && Number.isNaN(startTime?.getTime())) ||
      (endDate && Number.isNaN(endTime?.getTime()))
    ) {
      return res.status(400).json({ success: false, error: 'Invalid date range' })
    }

    if (startTime && endTime && startTime > endTime) {
      return res
        .status(400)
        .json({ success: false, error: 'Start date must be before or equal to end date' })
    }

    const accountInfo = await resolveAccountByPlatform(accountId, platform)
    if (!accountInfo) {
      return res.status(404).json({ success: false, error: 'Account not found' })
    }

    const allApiKeys = await apiKeyService.getAllApiKeys(true)
    const apiKeyNameCache = new Map(
      allApiKeys.map((key) => [key.id, key.name || key.label || key.id])
    )

    let keysToUse = apiKeyId ? allApiKeys.filter((key) => key.id === apiKeyId) : allApiKeys
    if (apiKeyId && keysToUse.length === 0) {
      keysToUse = [{ id: apiKeyId }]
    }

    const toUsageObject = (record) => ({
      input_tokens: record.inputTokens || 0,
      output_tokens: record.outputTokens || 0,
      cache_creation_input_tokens: record.cacheCreateTokens || 0,
      cache_read_input_tokens: record.cacheReadTokens || 0,
      cache_creation: record.cacheCreation || record.cache_creation || null
    })

    const withinRange = (record) => {
      if (!record.timestamp) {
        return false
      }
      const ts = new Date(record.timestamp)
      if (Number.isNaN(ts.getTime())) {
        return false
      }
      if (startTime && ts < startTime) {
        return false
      }
      if (endTime && ts > endTime) {
        return false
      }
      return true
    }

    const filteredRecords = []
    const modelSet = new Set()
    const apiKeyOptionMap = new Map()
    let earliestTimestamp = null
    let latestTimestamp = null

    const batchSize = 10
    for (let i = 0; i < keysToUse.length; i += batchSize) {
      const batch = keysToUse.slice(i, i + batchSize)
      const batchResults = await Promise.all(
        batch.map(async (key) => {
          try {
            const records = await redis.getUsageRecords(key.id, 5000)
            return { keyId: key.id, records: records || [] }
          } catch (error) {
            logger.debug(`⚠️ Failed to get usage records for key ${key.id}: ${error.message}`)
            return { keyId: key.id, records: [] }
          }
        })
      )

      for (const { keyId, records } of batchResults) {
        const apiKeyName = apiKeyNameCache.get(keyId) || (await getApiKeyName(keyId))
        for (const record of records) {
          if (record.accountId !== accountId) {
            continue
          }
          if (!withinRange(record)) {
            continue
          }
          if (model && record.model !== model) {
            continue
          }

          const accountType = record.accountType || accountInfo.platform || 'unknown'
          const normalizedModel = record.model || 'unknown'

          modelSet.add(normalizedModel)
          apiKeyOptionMap.set(keyId, { id: keyId, name: apiKeyName })

          if (record.timestamp) {
            const ts = new Date(record.timestamp)
            if (!Number.isNaN(ts.getTime())) {
              if (!earliestTimestamp || ts < earliestTimestamp) {
                earliestTimestamp = ts
              }
              if (!latestTimestamp || ts > latestTimestamp) {
                latestTimestamp = ts
              }
            }
          }

          filteredRecords.push({
            ...record,
            model: normalizedModel,
            accountType,
            apiKeyId: keyId,
            apiKeyName
          })
        }
      }
    }

    filteredRecords.sort((a, b) => {
      const aTime = new Date(a.timestamp).getTime()
      const bTime = new Date(b.timestamp).getTime()
      if (Number.isNaN(aTime) || Number.isNaN(bTime)) {
        return 0
      }
      return normalizedSortOrder === 'asc' ? aTime - bTime : bTime - aTime
    })

    const summary = {
      totalRequests: 0,
      inputTokens: 0,
      outputTokens: 0,
      cacheCreateTokens: 0,
      cacheReadTokens: 0,
      totalTokens: 0,
      totalCost: 0
    }

    for (const record of filteredRecords) {
      const usage = toUsageObject(record)
      const costData = CostCalculator.calculateCost(usage, record.model || 'unknown')
      const computedCost =
        typeof record.cost === 'number' ? record.cost : costData?.costs?.total || 0
      const totalTokens =
        record.totalTokens ||
        usage.input_tokens +
          usage.output_tokens +
          usage.cache_creation_input_tokens +
          usage.cache_read_input_tokens

      summary.totalRequests += 1
      summary.inputTokens += usage.input_tokens
      summary.outputTokens += usage.output_tokens
      summary.cacheCreateTokens += usage.cache_creation_input_tokens
      summary.cacheReadTokens += usage.cache_read_input_tokens
      summary.totalTokens += totalTokens
      summary.totalCost += computedCost
    }

    const totalRecords = filteredRecords.length
    const totalPages = totalRecords > 0 ? Math.ceil(totalRecords / pageSizeNumber) : 0
    const safePage = totalPages > 0 ? Math.min(pageNumber, totalPages) : 1
    const startIndex = (safePage - 1) * pageSizeNumber
    const pageRecords =
      totalRecords === 0 ? [] : filteredRecords.slice(startIndex, startIndex + pageSizeNumber)

    const enrichedRecords = []
    for (const record of pageRecords) {
      const usage = toUsageObject(record)
      const costData = CostCalculator.calculateCost(usage, record.model || 'unknown')
      const computedCost =
        typeof record.cost === 'number' ? record.cost : costData?.costs?.total || 0
      const totalTokens =
        record.totalTokens ||
        usage.input_tokens +
          usage.output_tokens +
          usage.cache_creation_input_tokens +
          usage.cache_read_input_tokens

      enrichedRecords.push({
        timestamp: record.timestamp,
        model: record.model || 'unknown',
        apiKeyId: record.apiKeyId,
        apiKeyName: record.apiKeyName,
        accountId,
        accountName: accountInfo.name || accountInfo.email || accountId,
        accountType: record.accountType,
        accountTypeName: accountTypeNames[record.accountType] || '未知渠道',
        inputTokens: usage.input_tokens,
        outputTokens: usage.output_tokens,
        cacheCreateTokens: usage.cache_creation_input_tokens,
        cacheReadTokens: usage.cache_read_input_tokens,
        ephemeral5mTokens: record.ephemeral5mTokens || 0,
        ephemeral1hTokens: record.ephemeral1hTokens || 0,
        totalTokens,
        isLongContextRequest: record.isLongContext || record.isLongContextRequest || false,
        cost: Number(computedCost.toFixed(6)),
        costFormatted:
          record.costFormatted ||
          costData?.formatted?.total ||
          CostCalculator.formatCost(computedCost),
        costBreakdown: record.costBreakdown || {
          input: costData?.costs?.input || 0,
          output: costData?.costs?.output || 0,
          cacheCreate: costData?.costs?.cacheWrite || 0,
          cacheRead: costData?.costs?.cacheRead || 0,
          total: costData?.costs?.total || computedCost
        },
        responseTime: record.responseTime || null
      })
    }

    return res.json({
      success: true,
      data: {
        records: enrichedRecords,
        pagination: {
          currentPage: safePage,
          pageSize: pageSizeNumber,
          totalRecords,
          totalPages,
          hasNextPage: totalPages > 0 && safePage < totalPages,
          hasPreviousPage: totalPages > 0 && safePage > 1
        },
        filters: {
          startDate: startTime ? startTime.toISOString() : null,
          endDate: endTime ? endTime.toISOString() : null,
          model: model || null,
          apiKeyId: apiKeyId || null,
          platform: accountInfo.platform,
          sortOrder: normalizedSortOrder
        },
        accountInfo: {
          id: accountId,
          name: accountInfo.name || accountInfo.email || accountId,
          platform: accountInfo.platform || platform || 'unknown',
          status: accountInfo.status ?? accountInfo.isActive ?? null
        },
        summary: {
          ...summary,
          totalCost: Number(summary.totalCost.toFixed(6)),
          avgCost:
            summary.totalRequests > 0
              ? Number((summary.totalCost / summary.totalRequests).toFixed(6))
              : 0
        },
        availableFilters: {
          models: Array.from(modelSet),
          apiKeys: Array.from(apiKeyOptionMap.values()),
          dateRange: {
            earliest: earliestTimestamp ? earliestTimestamp.toISOString() : null,
            latest: latestTimestamp ? latestTimestamp.toISOString() : null
          }
        }
      }
    })
  } catch (error) {
    logger.error('❌ Failed to get account usage records:', error)
    return res
      .status(500)
      .json({ error: 'Failed to get account usage records', message: error.message })
  }
})

module.exports = router
